home *** CD-ROM | disk | FTP | other *** search
/ Atari Forever 4 / Atari Forever 4 / Atari Forever 4.iso / SERIE_AI / AI_017 / INTERNET.TOS / SOFTWARE / TUWTCPSR / ICMP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-19  |  4.3 KB  |  78 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "ip.h"
  4. #include "icmp.h"
  5. #include "timer.h"
  6.  
  7. #include "nettrace.h"
  8.  
  9.  
  10. #define noDEBUG
  11.  
  12. static void pingtmo(TIMER);
  13. static int icmp_pingstate;
  14. static TIMER icmp_pingtm;
  15. static int pingseq;
  16. static PACKET *sent;
  17. static int snt_len;
  18. struct redent redtab[REDIRTABLEN];
  19. int rednext = 0;
  20. int holdback = 0;
  21. long icmp_counts[2] = {0L,0L};
  22.  
  23. int icmp_init(void)
  24. {
  25. int i;
  26.     if(!ip_open(IP_ICMP,icmp_handler,(int (*)(IP *))NULL)) return(FALSE);
  27.     icmp_pingstate = PGWAITING;
  28.     for(i=0; i< REDIRTABLEN; i++)
  29.         redtab[i].dst_inaddr = 0L;
  30.     return(TRUE);
  31. }
  32.  
  33.  
  34. int icmp_handler(PACKET *pkt,int len,INADDR fhost)
  35. {
  36. register IP *ip;
  37. register struct ping *e;
  38. struct redirect *rd;
  39. struct destun *pdp;
  40. u_short osum;
  41. char *data1, *data2;
  42. int i;
  43.  
  44.     ip = ip_head(pkt);
  45.     e = (struct ping *)ip_data(pkt);
  46.  
  47.     osum = e->pchksum;
  48.     e->pchksum = 0;
  49.  
  50.     if(chksum((u_short *)e,len,0) != osum) 
  51.     {
  52.         ip_free(pkt);
  53.         return(FALSE);
  54.     }
  55.     e->pchksum = osum;
  56.     icmp_counts[0]++;
  57.  
  58.     switch(e->ptype) 
  59.     {
  60.         case ICMP_ECHOREQ:            /* ping */
  61.             e->ptype = ICMP_ECHOREP;
  62.             e->pchksum = 0;
  63.             e->pchksum = chksum((u_short *)e,len,0);
  64.             ip->src_inaddr = ip->dst_inaddr;
  65.             ip->dst_inaddr = fhost;
  66.             icmp_counts[1]++;
  67.             i = ip_send(IP_ICMP, pkt, len, fhost);
  68.             ip_free(pkt);
  69.             return(i);
  70.         
  71.         case ICMP_DESTIN:
  72.             pdp = (struct destun *)e;
  73.             ip_dudemux(&pdp->dip);    /* DDP - upcall handler */
  74.             break;
  75.  
  76.         case ICMP_SOURCEQ:
  77.             holdback++;            /* hold back data - dst busy */
  78.             break;
  79.         
  80.         
  81.         case ICMP_REDIR:
  82.             rd = (struct redirect *)e;
  83.             for(i=0; i<REDIRTABLEN; i++)
  84.                 if(redtab[i].dst_inaddr == rd->rdip.dst_inaddr) 
  85.                 {
  86.                     redtab[i].gw_inaddr = rd->rdgw;
  87.                     ip_free(pkt);
  88.                     return(TRUE);
  89.                 }
  90.             redtab[rednext].dst_inaddr = rd->rdip.dst_inaddr;
  91.             redtab[rednext].gw_inaddr = rd->rdgw;
  92.             rednext++;
  93.             if(rednext >= REDIRTABLEN) rednext = 0;
  94.             break;
  95.  
  96.  
  97.         case ICMP_ECHOREP:
  98.             if(e->pseq != pingseq-1) 
  99.             {
  100.                 ip_free(pkt);
  101.                 return(FALSE);
  102.             }
  103.             data1 = ((ICMP_PACKET *)pkt)->icmp_data;
  104.             data2 = ((ICMP_PACKET *)sent)->icmp_data;
  105.             for(i=0; i < snt_len; i++)
  106.                 if(*data1++ != *data2++) 
  107.                 {
  108.                     icmp_pingstate = PGBADDATA;
  109.                     ip_free(pkt);
  110.                     return(FALSE);
  111.                 }
  112.  
  113.             icmp_pingstate = PGSUCCESS;
  114.             ip_free(pkt);
  115.             break;
  116.  
  117.         case ICMP_TIMEX:
  118.             break;
  119.             
  120.         case ICMP_PARAM:
  121.             break;
  122.             
  123.         case ICMP_TIMEREQ:
  124.             e->ptype = ICMP_TIMEREP;
  125.             e->pchksum = 0;
  126.             e->pchksum = chksum((u_short *)e, (int)sizeof(struct tstamp),0);
  127.             ip->src_inaddr = ip->dst_inaddr;
  128.             ip->dst_inaddr = fhost;
  129.             icmp_counts[1]++;
  130.             i = ip_send(IP_ICMP, pkt, (int)sizeof(struct tstamp), fhost);
  131.             ip_free(pkt);
  132.             return(i);
  133.  
  134.         case ICMP_INFO:
  135.             break;
  136.             
  137.     }
  138.     ip_free(pkt);
  139.     return(TRUE);
  140. }
  141.  
  142.  
  143.  
  144. int icmp_dstun(INADDR inaddr ,IP *ip,int type)
  145. {
  146. PACKET *p;
  147. register struct destun *d;
  148. int i;
  149.  
  150.     p = ip_alloc(512, 0);
  151.     if(p == NULL) return 0;
  152.  
  153.     d = (struct destun *)ip_data(p);
  154.     d->dtype = ICMP_DESTIN;
  155.     d->dcode = type;
  156.     for(i=0; i<(int)sizeof(IP)+8; i++)
  157.         ((char *)&d->dip)[i] = ((char *)ip)[i];
  158.     d->dchksum = 0;
  159.     d->dchksum = chksum((u_short *)d, (int)sizeof(struct destun),0);
  160.     icmp_counts[1]++;
  161.     i = ip_send(IP_ICMP, p, (int)sizeof(struct destun), inaddr);
  162.     ip_free(p);
  163.     return(i);
  164. }
  165.  
  166.  
  167. icmp_ping(INADDR fhost, int length)
  168. {
  169. PACKET *p;
  170. register struct ping *e;
  171. register char *data;
  172. int i;
  173.  
  174.     p = ip_alloc(40, 0);
  175.  
  176.     if(p == NULL) 
  177.     {
  178.         return PGNOSND;
  179.     }
  180.     e = (struct ping *)ip_data(p);
  181.     e->ptype = ICMP_ECHOREQ;
  182.     e->pcode = 0;
  183.     e->pid = 0;
  184.     e->pseq = pingseq++;
  185.  
  186.     /* Put 256 random numbers in the packet. */
  187.     data = ip_data(p) + ICMP_PKTSIZE;
  188.     for(i=0; i<length; i++) *data++ = rand();
  189.  
  190.     /* Calculate the checksum */
  191.     e->pchksum = 0;
  192.     if((ICMP_PKTSIZE+length)&1)
  193.         *data = 0;
  194.     e->pchksum = chksum((u_short *)e, (ICMP_PKTSIZE+length+1),0);
  195.     icmp_pingstate = PGWAITING;
  196.     sent = p;
  197.     snt_len = length;
  198.     icmp_pingtm = tm_alloc();
  199.     if(icmp_pingtm < 0) 
  200.     {
  201.         ip_free(p);
  202.         return(PGNOSND);
  203.     }
  204.     tm_set(tm_msec(ECHO_TIMEOUT), pingtmo, icmp_pingtm );
  205.     icmp_counts[1]++;
  206.     if(ip_send(IP_ICMP, p, ICMP_PKTSIZE+length, fhost) <= 0) 
  207.     {
  208.         tm_free(icmp_pingtm );
  209.         ip_free(p);
  210.         return(PGNOSND);
  211.     }
  212.     while(icmp_pingstate == PGWAITING)
  213.         net_demux(FALSE,DEMUX);
  214.     tm_free(icmp_pingtm );
  215.     ip_free(p);
  216.     sent = 0;
  217.     return(icmp_pingstate);
  218. }
  219.  
  220. static void pingtmo(TIMER tm) 
  221. {
  222.     if(icmp_pingtm == tm)
  223.         icmp_pingstate = PGTMO;
  224. }
  225.